#ifndef MUTEX_H_
#define MUTEX_H_

#include <pthread.h>

#include "Lock.hh"

//
/**
 * \file Mutex.hh
 * \author  jsk <jsk.jinsubkim@gmail.com>
 * \version 1.0
 *
 * \class Mutex Mutex.hh
 *
 * POSIX의 뮤텍스를 추상화 한다.
 */
class Mutex : public Lock
{
public:
	/**
	 * \name Mutex
	 */
	Mutex();
	
	/**
	 * \name ~Mutex
	 */
	~Mutex();
	
	/**
	 * \name lock
	 * 
	 * 크리티컬 섹션을 시작한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf lock();
	
	/**
	 * \name lockReadOnly
	 * 
	 * 크리티컬 섹션을 시작한다.
	 * 
	 * 뮤텍의 경우 읽기 모드가 없기 때문에 항상 에러를 반환한다.
	 * 
	 * \return 
	 * 
	 * 항상 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf lockReadOnly();
	
	/**
	 * \name unlock
	 * 
	 * 크리티컬 섹션을 종료한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf unlock();
	
	// frined
protected:
	/**
	 * 조건 변수는 뮤텍스 오브젝트를 직접 필요로 한다.
	 */
	friend class CondVar;
	
	/**
	 * \name tellMutexObject
	 * 
	 * 뮤텍스 오브젝트를 반환한다.
	 * 
	 * \return 
	 * 
	 * 뮤텍스 오브젝트.
	 */
	virtual pthread_mutex_t* tellObj();
	
	// Init
private:
	/**
	 * \name initMutexObj
	 * 
	 * 뮤텍스 오브젝트를 초기화 한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf initMutexObj();
	
	/**
	 * \name destroyMutexObj
	 * 
	 * 뮤텍스 오브젝트를 파기한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf destroyMutexObj();
	
	// Member
protected:
	/**
	 * 뮤텍스 오브젝트.
	 */
	pthread_mutex_t MutexObj;
	
	/**
	 * 락이 잠겼는지 나타낸다.
	 * 즉, lock 메소드가 호출되었는지 나타낸다.
	 */
	bool Locked;
	
	/**
	 * 인스턴스의 상태를 나타낸다.
	 * TRUE일 경우 정상, FALSE일 경우 비정상.
	 */
	bool State;
};

#endif //MUTEX_H_